package cn.chendd.shiro.examples.commponent;

import cn.chendd.shiro.examples.model.SysUser;
import cn.chendd.shiro.examples.service.ISysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;


/**
 * @author chendd
 * @date 2019/6/15 1:22
 * 自定义认证实现
 */
public class EncryptionRealmRedis extends AuthorizingRealm implements Serializable {

    private static final long serialVersionUID = 818010090715013851L;

    @Resource
    private RedisTemplate<Object, Object> redisTemplate;

    @Resource
    private ISysUserService sysUserService;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo author = new SimpleAuthorizationInfo();
        Set<String> roles = new HashSet<>();
        roles.add("userManager");
        author.setRoles(roles);
        Set<String> perms = new HashSet<>();
        perms.add("user:queryList");
        author.addStringPermissions(perms);
        //换成根据用户从数据库中读取
        return author;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        String userName = userToken.getUsername();
        SysUser sysUser = sysUserService.getSysUserByUserName(userName);
        if(sysUser == null){
            throw new UnknownAccountException();
        }
        String passWord = sysUser.getPassWord();
        if(! "ENABLE".equals(sysUser.getStatus())){
            throw new LockedAccountException();
        }
        String encodePassword = encodePassword(new String(userToken.getPassword()) , userName);
        if(!encodePassword.equals(passWord)){
            throw new IncorrectCredentialsException();
        } else if(false){
            //密码错误次数过多
            throw new ExcessiveAttemptsException();
        }

//        SimpleAuthenticationInfo auth = new SimpleAuthenticationInfo(sysUser , token.getCredentials() , this.getName());
        SimpleAuthenticationInfo auth = new SimpleAuthenticationInfo(sysUser.getUserName() , token.getCredentials() , this.getName());
        return auth;
    }

    @Override
    protected void doClearCache(PrincipalCollection principals) {
        redisTemplate.delete("shiro-cache-" + principals.getPrimaryPrincipal().toString());
    }

    public static String encodePassword(Object source, String salt) {
        Md5Hash md5 = new Md5Hash(source, salt, 7);
        return md5.toHex();
    }
}
